home *** CD-ROM | disk | FTP | other *** search
- /* Vanessa Board Interface, 7.1.92
- * implemented by Marcel Wiget, HB9RWM
- * for NOS (Copyright 1991 Phil Karn, KA9Q)
- *
- * Vanessa is part of the project SEPRAN,
- * Swiss Experimental Packet Radio Amateur Network,
- * of the SWISS-ARTG (Swiss Amateur Radio Teleprinter Group).
- * The full-size XT-Board contains 2 seperate interfaces
- * for high-speed AX.25 Layer-2 data streams. The data
- * can be received and sent via Dual-Port RAM embedded in a
- * KISS - Frame. Result: very less overhead for NOS to receive
- * and send a frame (e.g. only 1 memcpy for the hole frame).
- *
- * 10.11.91: Support of Vanessa Version 3.0 (word allignement RAM)
- * param command support
- * statistic support (e.g. if va0)
- * 14.11.91: set of Node ID and Alias
- * safe waiting for cmd completion
- * 19.11.91: info for 2nd port was wrong
- * 20.11.91: download added
- * 21.11.91: statistics for port 1 corrected, mbuf handling
- * 17.11.91: some adaptions made for use with WNOS - DB3FL
- * 24.11.91: dirps() and restore() inserted to mask interrupts
- * and changed buffer allocations and statistics
- * 'param'-command adapted to WNOS strategy
- * 7.01.92: if_param no longer supported by wnos, removed.
- */
-
- #include <stdio.h>
- #include <dos.h> /* for MK_FP */
- #include "global.h"
- #include "config.h"
- #ifdef VANESSA
- #include "proc.h"
- #include "commands.h"
- #include "mbuf.h"
- #include "ax25.h"
- #include "ip.h" /* def. Ip_Addr */
- #include "pktdrvr.h" /* def. for CL_AX25 */
- #include "trace.h"
- #include "vanessa.h"
-
- static struct vandrvr Vandrvr[VAN_MAX];
-
- /* Attach a Vanessa interface to the system
- * One board has 2 interfaces (Port 0 and 1)
- * Each Port must have its own interface,
- * attached via different dpram_base (dual port ram base address)
- * argv[0]: hardware type, must be "vanessa"
- * argv[1]: interface label, e.g., "va0"
- * argv[2]: port-nr, started with 0,1: board 0, with 2,3: board 1 etc.
- * argv[3]: maximum transmission unit, bytes (MTU) (optional)
- */
-
- int
- van_attach(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifvan;
- struct vandrvr *vp;
- struct dp_record far *dp;
- unsigned char *cp;
- int i;
-
- if(if_lookup(argv[1]) != NULLIF){
- tprintf(Ifexist,argv[1]);
- return -1;
- }
- if(*Mycall == '\0') { /* better to be sure */
- tputs(Nomycall);
- return -1;
- }
- for (i = 0; i < VAN_MAX; i++){
- if(Vandrvr[i].iface == NULLIF)
- break;
- }
- if (i >= VAN_MAX){
- tprintf("Max %d Vanessa drivers\n",VAN_MAX);
- return -1;
- }
- /* Create interface structure and fill in details */
- ifvan = (struct iface *)mxallocw(sizeof(struct iface));
- ifvan->addr = Ip_addr;
- ifvan->name = strxdup(argv[1]);
- ifvan->mtu = (4 == argc) ? atoi(argv[3]) : 256;
- setencap(ifvan,"AX25");
- ifvan->ioctl = van_ioctl;
- ifvan->status = van_status;
- ifvan->raw = van_raw;
- ifvan->stop = van_stop;
- ifvan->hwaddr = strxdup(Mycall);
- ifvan->dev = i;
- vp = &Vandrvr[i];
- vp->portnr = htoi(argv[2]);
- vp->dpram_base = MK_FP(BASE_SEGMENT + (vp->portnr << 8),0);
- vp->ioled = BASE_IO + (vp->portnr & 1) + (vp->portnr >> 1)*8 + 6;
- vp->iores = BASE_IO + (vp->portnr >> 1)*8;
- vp->iface = ifvan;
- van_reset(vp);
-
- /* if port 0 of selected board, then */
- /* set Node ID etc. */
- dp = vp->dpram_base;
- if (0 == (vp->portnr & 1)) {
- /* ok, let's do it */
- cp = dp->dp_cData;
- memcpy(cp,Mycall,AXALEN); /* MY_ID */
- cp += AXALEN;
- memcpy(cp,Mycall,AXALEN); /* MY_ALIAS */
- cp += AXALEN;
- *cp = (char) (0xff & vp->portnr);
- dp->dp_cCMD = CMD_ID_LOAD;
- }
-
- outportb(vp->ioled,LED_OFF);
-
- /* init statistics */
- vp->nTXwait = 0;
- vp->nRXmaxlen = 0;
- vp->nTXmaxlen = 0;
-
- init_maxheard(ifvan);
- init_flags(ifvan);
-
- ifvan->proc = newproc("van rx",256,van_rx,ifvan->dev,NULL,NULL,0);
-
- /* Link in the interface */
- ifvan->next = Ifaces;
- ifvan->niface = Niface++; /* WNOS router */
- Ifaces = ifvan;
-
- return 0;
- }
-
- /* van_ioctl:
- * perform device control on VANESSA KISS
- */
- static int
- van_ioctl(iface,argc,argv)
- struct iface *iface;
- int argc;
- char *argv[];
- {
- struct vandrvr *vp = &Vandrvr[iface->dev];
- struct dp_record far *p = vp->dpram_base;
- int pn = 0, v, i;
-
- if (2 == argc) {
- /* set value */
- pn = atoi(argv[0]); /* param-nr to change */
- v = (int16)atoi(argv[1]); /* value to be loaded */
- }
- for(i = 1;i < PARAM_COUNT; i++) {
- switch(i) {
- case TXDELAY:
- if (i==pn) {
- p->dp_pTXDelay = v;
- } else {
- tprintf("TxDelay %d\n", p->dp_pTXDelay);
- }
- break;
- case PERSIST:
- if (i==pn) {
- p->dp_pPersist = v;
- } else {
- tprintf("Persistence %d\n", p->dp_pPersist);
- }
- break;
- case SLOTTIME:
- if (i==pn) {
- p->dp_pSlottime = v;
- } else {
- tprintf("SlotTime %d\n", p->dp_pSlottime);
- }
- break;
- case TXTAIL:
- if (i==pn) {
- p->dp_pTXTail = v;
- } else {
- tprintf("TxTail %d\n", p->dp_pTXTail);
- }
- break;
- case FULLDUP:
- if (i==pn) {
- p->dp_pDuplex = v;
- } else {
- tprintf("Fullduplex %d\n", p->dp_pDuplex);
- }
- break;
- default:
- break;
- }
- if (pn){
- p->dp_reReadPar = 0;
- }
- }
- return 0;
- }
-
- /* send raw data packet on KISS VANESSA */
- int
- van_raw(iface,data)
- struct iface *iface;
- struct mbuf *data;
- {
- struct vandrvr *vp;
- struct dp_record far *p;
- int16 len = len_p(data);
- int i_state;
-
- if (0 < len) {
- vp = &Vandrvr[iface->dev];
- dump(iface,IF_TRACE_OUT,CL_AX25,data);
- p = vp->dpram_base;
- if (0 == p->dp_oFProd)
- vp->nTXwait++;
- while ( (NULLIF != vp->iface) && (0 == p->dp_oFProd) ) {
- /* still busy, should not happen */
- pwait(NULL);
- }
- if (NULLIF != vp->iface) {
- /* send it */
- i_state = dirps();
- p->dp_oLFrm = len;
- len=dqdata(data,(char *)&p->dp_oBuffer[0],len);
- if (len > vp->nTXmaxlen)
- vp->nTXmaxlen = len;
- p->dp_oFProd = 0; /* send
- it */
- restore(i_state);
- }
- } else
- free_p(data);
- return 0;
- }
-
- static void
- van_rx(dev,p1,p2)
- int dev;
- void *p1;
- void *p2;
- {
- struct vandrvr *vp = &Vandrvr[dev];
- struct mbuf *rcvbuf;
- struct phdr phdr;
- struct dp_record far *p = vp->dpram_base;
- char *cp;
- int16 len;
- int i_state;
-
- while (vp->iface != NULLIF){
- if (0 == p->dp_iFProd) {
- /* data arrived */
- len = p->dp_iLFrm;
- if (len > vp->nRXmaxlen)
- vp->nRXmaxlen = len;
- if (len > 0) {
- i_state = dirps();
- outportb(vp->ioled,LED_ON);
- rcvbuf = ambufw(len+sizeof(phdr));
-
- cp = rcvbuf->data + sizeof(phdr);
- memcpy(cp,(char *)&p->dp_iBuffer[0],len);
- rcvbuf->cnt = sizeof(phdr) + len;
- rcvbuf->next = NULLBUF;
- phdr.iface = vp->iface;
- phdr.type = CL_AX25;
- memcpy(rcvbuf->data,(char *)&phdr,sizeof(phdr));
- restore(i_state);
- enqueue(&Hopper,rcvbuf);
- }
- outportb(vp->ioled,LED_OFF);
- p->dp_iFProd = 1; /* open DPRAM for next frame */
- }
- pwait(NULL);
- }
- }
-
- /* shut down the VANESSA interface */
- static int
- van_stop(iface)
- struct iface *iface;
- {
- struct vandrvr *vp = &Vandrvr[iface->dev];
-
- if (NULLIF != vp->iface) {
- vp->iface = NULLIF;
- }
- return 0;
- }
-
- void
- van_reset(vp)
- struct vandrvr *vp;
- {
- outportb(vp->iores,0xff);
- pwait(NULL);
- outportb(vp->iores,0);
- }
-
-
- int32
- cova(p,n)
- char *p;
- int16 n;
- {
- int i;
- long rv = 0;
- n--;
- for (i=n;i>=0;i--) rv = (rv<<8)+(p[i]&0xff);
- return rv;
- }
-
-
- /* Show vanessa port status */
- static int
- van_status(iface)
- struct iface *iface;
- {
- struct vandrvr *vp = &Vandrvr[iface->dev];
- char *cp;
- int i;
- int i_state;
-
- struct dp_record far *dp0 =
- MK_FP(FP_SEG(vp->dpram_base)-((vp->portnr & 1)<<8),0);
- struct dp_record far *dp1 =
- MK_FP(FP_SEG(dp0)+0x0100,0);
-
- if (NULLIF != vp->iface) {
- i_state = dirps();
- dp0->dp_cCMD = CMD_POINTER;
- i = 0;
- while (i<CMD_TIMEOUT && dp1->dp_cCMD!=(CMD_POINTER|0xf000) ){
- i++;
- pwait(NULL);
- }
- if (CMD_TIMEOUT==i) {
- tputs("No valid data!\n");
- } else {
- tprintf("\n Port %u: DP-RAM=%p TXwait=%u TXmaxlen=%u RXmaxlen=%u",
- vp->portnr,vp->dpram_base,
- vp->nTXwait,vp->nTXmaxlen,vp->nRXmaxlen);
- cp = dp1->dp_cData;
- tprintf("\n SWrev=%x\.%02x Rst=%u Board=%u",
- cp[cRev+1],cp[cRev],cova(&cp[cRst],2),cp[cPNr] & 0xf);
- cp += (vp->portnr&1 ? cPort1 : 0);
- tprintf(" Counters: Rx=%lu Tx=%lu TxKu=%lu\n",
- cova(&cp[cRx],3),cova(&cp[cTx],3),cova(&cp[cTxKu],3));
- tprintf("\n RxBf TxBf RxBe TxBe RFlI TflC TFlI RCRC "
- "RxOv TxTo SyTx SyRx RxAb TxUdr\n ");
- for (i = cRxBf; i <= cTxUdr; i += 2)
- tprintf("%5u",cova(&cp[i],2));
- tputs("\n");
- }
- restore(i_state);
- }
- return 0;
- }
-
- #endif /* VANESSA */
-